package io.gitee.kotle.android.utils

import android.content.Context
import android.graphics.drawable.Drawable
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.RecyclerView
import io.gitee.kotle.android.iInterface.ILifecycleObserver
import kotlinx.coroutines.*

/**
 *
 * 描述：
 *
 * 创建人：jiale.wei
 * 创建时间：2021/11/24 9:49 上午
 *
 */
/**
 * 结束activity
 */
fun Fragment.finishActivity() {
    activity?.finish()
}

/**
 * 结束activity
 */
fun Fragment.finishActivityAfterTransition() {
    activity?.finishAfterTransition()
}

/**
 * commitFragment
 */
inline fun Fragment.commitFragment(block: (FragmentTransaction) -> FragmentTransaction): Int? {
    return ignoreError {
        childFragmentManager.beginTransaction()
            .let(block)
            .commit()
    }
}

/**
 * commitFragment
 */
inline fun Fragment.commitFragmentAllowingStateLoss(block: (FragmentTransaction) -> FragmentTransaction): Int? {
    return ignoreError {
        childFragmentManager.beginTransaction()
            .let(block)
            .commitAllowingStateLoss()
    }
}

/**
 * commitFragment
 */
inline fun Fragment.commitFragmentNow(block: (FragmentTransaction) -> FragmentTransaction) {
    ignoreError {
        childFragmentManager.beginTransaction()
            .let(block)
            .commitNow()
    }
}

/**
 * commitFragment
 */
inline fun Fragment.commitFragmentNowAllowingStateLoss(block: (FragmentTransaction) -> FragmentTransaction) {
    ignoreError {
        childFragmentManager.beginTransaction()
            .let(block)
            .commitNowAllowingStateLoss()
    }
}

/**
 * commitFragment
 */
inline fun AppCompatActivity.commitFragment(block: (FragmentTransaction) -> FragmentTransaction): Int? {
    return ignoreError {
        supportFragmentManager.beginTransaction()
            .let(block)
            .commit()
    }
}

/**
 * commitFragment
 */
inline fun AppCompatActivity.commitFragmentAllowingStateLoss(block: (FragmentTransaction) -> FragmentTransaction): Int? {
    return ignoreError {
        supportFragmentManager.beginTransaction()
            .let(block)
            .commitAllowingStateLoss()
    }
}

/**
 * commitFragment
 */
inline fun AppCompatActivity.commitFragmentNow(block: (FragmentTransaction) -> FragmentTransaction) {
    ignoreError {
        supportFragmentManager.beginTransaction()
            .let(block)
            .commitNow()
    }
}

/**
 * commitFragment
 */
inline fun AppCompatActivity.commitFragmentNowAllowingStateLoss(block: (FragmentTransaction) -> FragmentTransaction) {
    ignoreError {
        supportFragmentManager.beginTransaction()
            .let(block)
            .commitNowAllowingStateLoss()
    }
}

/**
 * 添加生命周期监听
 */
fun LifecycleOwner.addLifecycleListener(observer: ILifecycleObserver): ILifecycleObserver {
    this.lifecycle.addObserver(observer)
    return observer
}

/**
 * 生命周期监听
 */
inline fun LifecycleOwner.addDoOnCreate(crossinline block: (LifecycleOwner) -> Unit): ILifecycleObserver {
    return this.addLifecycleListener(object : ILifecycleObserver {
        override fun onCreate(owner: LifecycleOwner) {
            super.onCreate(owner)

        }
    })
}

/**
 * 生命周期监听
 */
inline fun LifecycleOwner.addDoOnStart(crossinline block: (LifecycleOwner) -> Unit): ILifecycleObserver {
    return this.addLifecycleListener(object : ILifecycleObserver {
        override fun onStart(owner: LifecycleOwner) {
            super.onStart(owner)
            block.invoke(owner)
        }
    })
}

/**
 * 生命周期监听
 */
inline fun LifecycleOwner.addDoOnResume(crossinline block: (LifecycleOwner) -> Unit): ILifecycleObserver {
    return this.addLifecycleListener(object : ILifecycleObserver {
        override fun onResume(owner: LifecycleOwner) {
            super.onResume(owner)
            block.invoke(owner)
        }
    })
}

/**
 * 生命周期监听
 */
inline fun LifecycleOwner.addDoOnPause(crossinline block: (LifecycleOwner) -> Unit): ILifecycleObserver {
    return this.addLifecycleListener(object : ILifecycleObserver {
        override fun onPause(owner: LifecycleOwner) {
            super.onPause(owner)
            block.invoke(owner)
        }
    })
}

/**
 * 生命周期监听
 */
inline fun LifecycleOwner.addDoOnStop(crossinline block: (LifecycleOwner) -> Unit): ILifecycleObserver {
    return this.addLifecycleListener(object : ILifecycleObserver {
        override fun onStop(owner: LifecycleOwner) {
            super.onStop(owner)
            block.invoke(owner)
        }
    })
}

/**
 * 生命周期监听
 */
inline fun LifecycleOwner.addDoOnDestroy(crossinline block: (LifecycleOwner) -> Unit): ILifecycleObserver {
    return this.addLifecycleListener(object : ILifecycleObserver {
        override fun onDestroy(owner: LifecycleOwner) {
            super.onDestroy(owner)
            block.invoke(owner)
        }
    })
}

/**
 * 从资源文件中获取颜色
 */
fun Fragment.getColor(@ColorRes color: Int): Int {
    return ContextCompat.getColor(requireContext(), color)
}

/**
 * 从资源文件中获取图片
 */
fun Fragment.getDrawable(@DrawableRes drawable: Int): Drawable? {
    return ContextCompat.getDrawable(requireContext(), drawable)
}


/**
 * 从资源文件中获取颜色
 */
fun RecyclerView.ViewHolder.getColor(@ColorRes color: Int): Int {
    return ContextCompat.getColor(itemView.context, color)
}

fun RecyclerView.ViewHolder.getString(@StringRes strRes: Int): String {
    return itemView.context.getString(strRes)
}

val RecyclerView.ViewHolder.context: Context
    get() = itemView.context

val RecyclerView.ViewHolder.appCompatActivity: Context
    get() = itemView.context as AppCompatActivity

/**
 * 从资源文件中获取图片
 */
fun RecyclerView.ViewHolder.getDrawable(@DrawableRes drawable: Int): Drawable? {
    return ContextCompat.getDrawable(itemView.context, drawable)
}

/**
 * 预留导航栏空间,
 * 一般只是对话框使用
 */
fun Fragment.compatNavigationBars() {
    val decorView = requireView()
    //预留导航栏的空间
    ViewCompat.setOnApplyWindowInsetsListener(decorView) { _, insets ->
        requireView().updatePadding(
            bottom = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
        )
        insets
    }
}

/**
 * 利用[LifecycleOwner]开启轮询
 */
inline fun LifecycleOwner.safeLoop(
    interval: Long = 1000,
    delayStart: Long = 0,
    crossinline block: () -> Unit
): Job {
    return lifecycleScope.safeLoop(interval, delayStart, block)
}

/**
 * 利用[LifecycleOwner]开启轮询
 */
inline fun Fragment.safeLoop(
    interval: Long = 1000,
    delayStart: Long = 0,
    crossinline block: () -> Unit
): Job {
    return viewLifecycleOwner.safeLoop(interval, delayStart, block)
}

/**
 * 利用[CoroutineScope]开启轮询
 */
inline fun CoroutineScope.safeLoop(
    interval: Long = 1000,
    delayStart: Long = 0,
    crossinline block: () -> Unit
): Job {
    return launch {
        if (delayStart > 0) {
            delay(delayStart)
        }
        while (this.isActive) {
            block.invoke()
            delay(interval)
        }
    }
}

/**
 * 利用[CoroutineScope]开启倒计时
 */
inline fun CoroutineScope.safeCountDown(
    total: Int,
    end: Int = 0,
    interval: Long = 1000,
    delayStart: Long = 0,
    crossinline block: (Int) -> Unit
): Job {
    return launch {
        var count = total
        if (delayStart > 0) {
            delay(delayStart)
        }
        while (this.isActive && count >= end) {
            block.invoke(count)
            count--
            if (count >= end) {
                delay(interval)
            }
        }
    }
}

/**
 * 利用[CoroutineScope]开启倒计时
 */
inline fun Fragment.safeCountDown(
    total: Int,
    end: Int = 0,
    interval: Long = 1000,
    delayStart: Long = 0,
    crossinline block: (Int) -> Unit
): Job {
    return viewLifecycleOwner.lifecycleScope.safeCountDown(total, end, interval, delayStart, block)
}





